<script setup lang="ts" name="GoodsSku">
import {GoodsInfo} from '@/types/good'
import {Spec,SpecValue} from '@/types/good'
import bwPowerSet from '@/utils/power-set'
// console.log(bwPowerSet(['黑色','中国','30cm']));

const props = defineProps<{
  goods:GoodsInfo,
  skuId?:string
}>()
const emit = defineEmits<{
  (e:'changeSku',skuId:string):void
}>()
const changeSelect = (item:Spec,sub:SpecValue)=>{
 
  // 如果是禁用状态 就不能点击出现高亮
  if(sub.disabled)return
  // 判断
  if(sub.selected){
    sub.selected = false
  }else{
    item.values.forEach(item=>item.selected = false)
    sub.selected = true
  }
   // 在点击规格的时候，需要更新禁用状态
  // 更新禁用状态
  
  updateDisabledStatus()
  // 判断规格是否全部选中 
  const selected = getSelectedSpec().filter(item=>item)
  if(selected.length===props.goods.specs.length){
    // 全部选中之后 在pathMap中找到对应的id
    const key = selected.join('+')
    const [skuId] = pathMap[key]
    emit('changeSku',skuId)
  }else{
    emit('changeSku','')
  }
}
// 筛选出选中的规格
const getSelectedSpec =()=>{
  const arr:string[] = []
   props.goods.specs.forEach(item=>{
    // 找到选中的一项
    const spec = item.values.find(sub=>sub.selected)
    arr.push(spec?spec.name:'')
    })  
    return arr
}
getSelectedSpec()
const getPathMap = ()=>{
  const pathMap:{
    [key:string]:string[]
  } = {}
  // 第一步  筛选出库存为0的规格
  const kus = props.goods.skus.filter(item=>item.inventory>0)
  // 第二步  遍历有效的sku 获取幂集
 kus.forEach(item=>{
  const arr = item.specs.map(item=>item.valueName)
  // 获取幂集
  const powerSet = bwPowerSet(arr)
  // console.log(powerSet);
  powerSet.forEach(sub=>{
    const key = sub.join('+')
    if(key in pathMap ){
      // 存在的话
      pathMap[key].push(item.id)
    }else{
      // 不存在的话
      pathMap[key] = [item.id]
    }
  })
  
 })
  return pathMap
}
const pathMap = getPathMap()
// 判断是否禁用
const updateDisabledStatus = ()=>{
  // 选择的规格
  const selectedArr = getSelectedSpec()
  props.goods.specs.forEach((item,index)=>{
    item.values.forEach(sub=>{
      // 拷贝一份数据 
      const temp = [...selectedArr]
      // 用外面一层的下标来赋值
      temp[index] = sub.name
      // 选中的规格 有值转化为字符串
      const key = temp.filter(item=>item).join('+')      
      // 如果规格名字在路径字典中是否存在
      // 通过选择的组合 在路径字典中查找是否存在
      if(key in pathMap){
        // 存在 不禁用
        sub.disabled = false
      }else{
        // 不存在 禁用
        sub.disabled = true
      }
    })
  })

}
// 初始化默认选中
const initSelectedSpec = ()=>{
  const sku = props.goods.skus.find(item=>item.id===props.skuId)
  if(sku){
    // 如果传入的skuId能够找到的话
    props.goods.specs.forEach((item,index)=>{
      // 找到相关的属性
      const value = sku.specs[index].valueName
      // 在每一项中找到和相关的属性名字相同的  进行选择的设置 初始化
      const spec =item.values.find(sub=>sub.name===value)
      spec!.selected = true

    })
  }
}
initSelectedSpec()//先默认选中
updateDisabledStatus () //在进行禁用
</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{item.name}}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
        <img
          :class="{selected:sub.selected,disabled:sub.disabled}"
          :src="sub.picture"
          alt=""
          v-if="sub.picture"
          @click=changeSelect(item,sub)
        />
        <span v-else @click=changeSelect(item,sub) 
        :class="{selected:sub.selected,disabled:sub.disabled}">{{sub.name}}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>

